/*
 * $Id: LogEventService.java 17 2014-08-28 10:52:50Z ratking $
 *
 * Copyleft (C) 2014 RatKing. All wrongs reserved.
 */
package cn.ratking.demo.jaws7.system.service;

import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;

import org.fluttercode.datavalve.DefaultPaginator;
import org.fluttercode.datavalve.Paginator;
import org.fluttercode.datavalve.el.ExpressionParameterResolver;
import org.fluttercode.datavalve.provider.jpa.JpaQueryProvider;
import org.slf4j.Logger;
import org.primefaces.model.SortOrder;

import cn.ratking.demo.jaws7.common.DateUtils;
import cn.ratking.demo.jaws7.common.StringUtils;
import cn.ratking.demo.jaws7.model.LogEvent;
import cn.ratking.demo.jaws7.resource.JawsPU;
import cn.ratking.demo.jaws7.system.vo.LogEventSearchCriteria;

/**
 * 日志事件服务
 *
 * @author ljg
 */
@Stateless
public class LogEventService {

    /** 系统日志 */
    @Inject
    private transient Logger log;
    /** 实体管理器 */
    @Inject
    @JawsPU
    private EntityManager em;

    public void create(LogEvent logEvent) {
//        if (logEvent.getUserName() == null) {
//            // 无用户名或匿名用户
//            logEvent.setUserName("N/A");
//        }
        String description = logEvent.getDescription();
        if (description != null && description.getBytes().length > LogEvent.LOGLEVEL_DESC_BYTES) {
            // 避免描述信息超长
            description = StringUtils.getLimitLengthString(description, LogEvent.LOGLEVEL_DESC_BYTES, "…");
            logEvent.setDescription(description);
        }
        if (logEvent.getCreateTime() == null) {
            // 设置创建时间
            logEvent.setCreateTime(new Date());
        }
        em.persist(logEvent);
    }

    public void deleteById(Long logEventId) {
        String ql = "DELETE FROM LogEvent t"
                + " WHERE t.logEventId = :logEventId";
        em.createQuery(ql)
                .setParameter("logEventId", logEventId)
                .executeUpdate();
    }

    public void batchDelete(List<Long> logEventIdList) {
        String ql = "DELETE FROM LogEvent t"
                + " WHERE t.logEventId IN :logEventIdList";
        em.createQuery(ql)
                .setParameter("logEventIdList", logEventIdList)
                .executeUpdate();
    }

    public LogEvent findById(Long logEventId) {
        return em.find(LogEvent.class, logEventId);
    }

    /**
     * 获得符合查询条件的当前页结果列表
     *
     * @param first 第一条记录(从0开始)
     * @param pageSize 页面行数
     * @param sortField 排序字段
     * @param sortOrder 排序方向
     * @param filters 过滤条件
     * @param searchCriteria 查询条件
     * @return 结果列表
     */
    public List<LogEvent> getResultList(int first, int pageSize,
            String sortField, SortOrder sortOrder,
            LogEventSearchCriteria searchCriteria) {
        // 查询提供器
        JpaQueryProvider<LogEvent> provider = new JpaQueryProvider<LogEvent>();
        // 设置实体管理器
        provider.setEntityManager(em);
        // 设置实体类型与别名
        provider.init(LogEvent.class, "t");
        // 初始化排序字段映射，可避免恶意SQL注入
        provider.getOrderKeyMap().put("logEventId", "t.logEventId");
        provider.getOrderKeyMap().put("userId", "t.userId");
        provider.getOrderKeyMap().put("userName", "t.userName");
        provider.getOrderKeyMap().put("description", "t.description");
        provider.getOrderKeyMap().put("createTime", "t.createTime");
        provider.getOrderKeyMap().put("computerIP", "t.computerIP");
        // 设置表达式参数解析器
        provider.addParameterResolver(new ExpressionParameterResolver());
        // 设置分页与排序
        Paginator paginator = new DefaultPaginator();
        paginator.setFirstResult(first);
        paginator.setMaxRows(pageSize);
        if (sortField == null) {
            sortField = "logEventId";
            sortOrder = SortOrder.DESCENDING;
        }
        paginator.setOrderKey(sortField);
        paginator.setOrderAscending(sortOrder == SortOrder.ASCENDING);
        // 设置查询约束
        setRestrictions(provider, searchCriteria);
        // 返回查询结果
        return provider.fetchResults(paginator);
    }

    /**
     * 获得符合查询条件的记录总数
     *
     * @param searchCriteria 查询条件
     * @return 记录总数
     */
    public int getRowCount(LogEventSearchCriteria searchCriteria) {
        // 查询提供器
        JpaQueryProvider<LogEvent> provider = new JpaQueryProvider<LogEvent>();
        // 设置实体管理器
        provider.setEntityManager(em);
        // 设置实体类型与别名
        provider.init(LogEvent.class, "t");
        // 设置表达式参数解析器
        provider.addParameterResolver(new ExpressionParameterResolver());
        // 设置查询约束
        setRestrictions(provider, searchCriteria);
        // 返回查询结果
        return provider.fetchResultCount();
    }

    /**
     * 设置查询约束
     *
     * @param queryProvider 查询提供器
     * @param searchCriteria 查询条件
     */
    private void setRestrictions(JpaQueryProvider<LogEvent> queryProvider, LogEventSearchCriteria searchCriteria) {
        queryProvider.getRestrictions().clear();

        // 检查调整查询条件中的开始与结束时间
        searchCriteria.checkDate();

        queryProvider.addRestrictionStr("t.userId = :param",
                searchCriteria.getUserId());
        queryProvider.addRestrictionStr("t.userName like :param",
                "%" + searchCriteria.getUserName() + "%",
                searchCriteria.getUserName());
        queryProvider.addRestrictionStr("t.description like :param",
                "%" + searchCriteria.getDescription() + "%",
                searchCriteria.getDescription());
        queryProvider.addRestriction("t.createTime >= :param",
                DateUtils.getBeginDate(searchCriteria.getBeginDate()),
                searchCriteria.getBeginDate());
        queryProvider.addRestriction("t.createTime <= :param",
                DateUtils.getEndDate(searchCriteria.getEndDate()),
                searchCriteria.getEndDate());
    }
}
